package org.asiainfo.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.mybatisflex.core.update.UpdateChain;
import org.asiainfo.common.core.constant.AnnouncementConstants;
import org.asiainfo.common.core.constant.UserConstants;
import org.asiainfo.common.core.utils.StringUtils;
import org.asiainfo.common.mybatis.stream.core.page.TableDataInfo;
import org.asiainfo.common.mybatis.stream.core.page.PageQuery;
import org.asiainfo.common.satoken.utils.LoginHelper;
import org.asiainfo.system.domain.SysAnnouncement;
import org.asiainfo.system.domain.SysUser;
import org.asiainfo.system.domain.table.SysAnnouncementSendTableDef;
import org.asiainfo.system.domain.table.SysAnnouncementTableDef;
import org.asiainfo.system.domain.table.SysUserTableDef;
import org.asiainfo.system.domain.vo.AnnouncementSendVo;
import org.asiainfo.system.domain.vo.SysAnnouncementSendVo;
import org.asiainfo.system.domain.bo.SysAnnouncementSendBo;
import org.asiainfo.system.domain.SysAnnouncementSend;
import org.asiainfo.system.mapper.SysUserMapper;
import org.asiainfo.system.service.SysAnnouncementSendService;
import org.springframework.stereotype.Service;
import org.asiainfo.common.core.utils.MapstructUtils;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.asiainfo.system.mapper.SysAnnouncementSendMapper;
import com.mybatisflex.core.paginate.Page;

import java.util.Date;
import java.util.Map;
import java.util.Collection;
import java.util.List;

/**
 * 用户通告阅读标记表(SysAnnouncementSend)表服务实现类
 *
 * @author dotor-ww
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysAnnouncementSendServiceImpl extends ServiceImpl<SysAnnouncementSendMapper, SysAnnouncementSend> implements SysAnnouncementSendService {

    private final SysUserMapper sysUserMapper;

    /**
     * 查询
     *
     * @param sysAnnouncementSendBo 筛选条件
     * @return 查询结果
     */
    @Override
    public List<SysAnnouncementSendVo> queryList(SysAnnouncementSendBo sysAnnouncementSendBo) {
        Map<String, Object> params = sysAnnouncementSendBo.getParams();
        QueryWrapper query = query();
        return listAs(query, SysAnnouncementSendVo.class);
    }

    /**
     * 通过id查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public SysAnnouncementSendVo queryById(Long id) {
        return getOneAs(query().eq(SysAnnouncementSend::getId, id), SysAnnouncementSendVo.class);
    }

    /**
     * 分页查询
     *
     * @param sysAnnouncementSendBo 筛选条件
     * @param pageQuery             分页对象
     * @return 查询结果
     */
    @Override
    public TableDataInfo<SysAnnouncementSendVo> queryPageList(SysAnnouncementSendBo sysAnnouncementSendBo, PageQuery pageQuery) {
        Map<String, Object> params = sysAnnouncementSendBo.getParams();
        QueryWrapper query = query().between(SysAnnouncementSend::getCreateTime, params.get("beginTime"), params.get("endTime"),
            ObjectUtil.isNotNull(params.get("beginTime")) && ObjectUtil.isNotNull(params.get("endTime")));
        pageQuery.buildOrder(query);
        Page<SysAnnouncementSendVo> page = pageAs(pageQuery.buildPage(), query, SysAnnouncementSendVo.class);
        return TableDataInfo.build(page);
    }

    /**
     * 新增数据
     *
     * @param sysAnnouncementSendBo 实例对象
     * @return 实例对象
     */
    @Override
    public Boolean insertByBo(SysAnnouncementSendBo sysAnnouncementSendBo) {
        SysAnnouncementSend sysAnnouncementSend = MapstructUtils.convert(sysAnnouncementSendBo, SysAnnouncementSend.class);
        return save(sysAnnouncementSend);
    }

    /**
     * 修改数据
     *
     * @param sysAnnouncementSendBo 实例对象
     * @return 实例对象
     */
    @Override
    public Boolean updateByBo(SysAnnouncementSendBo sysAnnouncementSendBo) {
        SysAnnouncementSend sysAnnouncementSend = MapstructUtils.convert(sysAnnouncementSendBo, SysAnnouncementSend.class);
        return updateById(sysAnnouncementSend);
    }

    /**
     * 通过主键删除数据
     *
     * @param ids 主键
     * @return 是否成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return removeByIds(ids);
    }

    /**
     * 通过通告ID修改数据
     *
     * @param antId 通告ID
     * @return 修改结果
     */
    @Override
    public Boolean editByAntIdAndUserId(Long antId) {
        return updateChain().set(SysAnnouncementSend::getReadFlag, AnnouncementConstants.HAS_READ_FLAG)
            .set(SysAnnouncementSend::getReadTime, new Date())
            .eq(SysAnnouncementSend::getAntId, antId)
            .eq(SysAnnouncementSend::getUserId, LoginHelper.getUserId())
            .update();
    }

    /**
     * 获取我的消息
     *
     * @param title     标题
     * @param pageQuery 分页对象
     * @return 我的消息
     */
    @Override
    public TableDataInfo<AnnouncementSendVo> getMyAnnouncementSend(String title, PageQuery pageQuery) {
        QueryWrapper query = query().select(SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.ID,
                SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.ANT_ID,
                SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.USER_ID,
                SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.READ_FLAG,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.TITLE,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.MSG_CONTENT,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.SENDER,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.PRIORITY,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.SEND_TIME,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.BUS_ID,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.BUS_TYPE,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.OPEN_TYPE,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.OPEN_PAGE,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.MSG_ABSTRACT,
                SysAnnouncementTableDef.SYS_ANNOUNCEMENT.MSG_CATEGORY)
            .from(SysAnnouncementSend.class)
            .leftJoin(SysAnnouncement.class)
            .on(SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.ANT_ID.eq(SysAnnouncementTableDef.SYS_ANNOUNCEMENT.ID))
            .where(SysAnnouncementTableDef.SYS_ANNOUNCEMENT.SEND_STATUS.eq(AnnouncementConstants.PUBLISHED))
            .and(SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.USER_ID.eq(LoginHelper.getUserId()))
            .and(SysAnnouncementTableDef.SYS_ANNOUNCEMENT.TITLE.like(title, StringUtils.isNotBlank(title))).
            orderBy(SysAnnouncementSendTableDef.SYS_ANNOUNCEMENT_SEND.READ_FLAG.desc(), SysAnnouncementTableDef.SYS_ANNOUNCEMENT.SEND_TIME.desc());
        Page<AnnouncementSendVo> page = pageAs(pageQuery.buildPage(), query, AnnouncementSendVo.class);
        return TableDataInfo.build(page);
    }

    /**
     * 一键阅读
     *
     * @return 阅读结果
     */
    @Override
    public Boolean readAll() {
        return UpdateChain.of(SysAnnouncementSend.class)
            .set(SysAnnouncementSend::getReadFlag, AnnouncementConstants.HAS_READ_FLAG)
            .set(SysAnnouncementSend::getReadTime, new Date())
            .eq(SysAnnouncementSend::getUserId, LoginHelper.getUserId())
            .update();
    }

    /**
     * 批量插入
     *
     * @param commentId 评论ID
     * @param tenantId  租户ID
     */
    @Override
    public void batchInsert(Long commentId, Long tenantId) {
        QueryWrapper query = query()
            .select(SysUserTableDef.SYS_USER.USER_ID)
            .from(SysUser.class)
            .where(SysUserTableDef.SYS_USER.USER_STATUS.eq(UserConstants.NORMAL));
        List<Long> userIds = sysUserMapper.selectListByQueryAs(query, Long.class);

        if (CollUtil.isNotEmpty(userIds)) {
            List<SysAnnouncementSend> sysAnnouncementSends = CollUtil.newArrayList();
            for (Long userId : userIds) {
                SysAnnouncementSend sysAnnouncementSend = new SysAnnouncementSend();
                sysAnnouncementSend.setAntId(commentId);
                sysAnnouncementSend.setUserId(userId);
                sysAnnouncementSend.setReadFlag(AnnouncementConstants.NO_READ_FLAG);
                sysAnnouncementSends.add(sysAnnouncementSend);
            }
            saveBatch(sysAnnouncementSends);
        }
    }
}
